package org.rupa.core.registry.center.zk;

import org.apache.zookeeper.CreateMode;
import org.rupa.common.constant.HttpPathConstant;
import org.rupa.common.constant.ZkPathConstant;
import org.rupa.common.model.ForwardInfo;
import org.rupa.common.model.ServiceInfo;
import org.rupa.common.util.HttpUtil;
import org.rupa.core.poll.PollFactory;
import org.rupa.core.registry.center.AbstractRegistryCenterFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.client.RestTemplate;

import java.util.List;

public class ZkRegistryCenter extends AbstractRegistryCenterFactory {
    public ZkRegistryCenter() {
        super();
    }

    @Autowired
    private PollFactory pollFactory;

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public void register(ServiceInfo serviceInfo) {
        try {
            getZooKeeper()
                    .create()
                    .creatingParentsIfNeeded()
                    .withMode(CreateMode.PERSISTENT)
                    .forPath(serviceInfo.toString());

            log.info("服务 " + serviceInfo + " 已注册");
            startHeartbeatThread(serviceInfo);
            log.info("服务 " + serviceInfo + " 开始监听");
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    @Override
    public void unregister(ServiceInfo serviceInfo) {
        try {
            getZooKeeper()
                    .delete()
                    .deletingChildrenIfNeeded()
                    .forPath(serviceInfo.toString());

            log.info("服务 " + serviceInfo + " 已销毁");
            destroy(serviceInfo.getName());
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    @Override
    public Object forward(ForwardInfo forwardInfo) {
        String url = forwardInfo.getUrl();

        String serviceName = getServiceNameFromUrl(url);
        String requestPath = getRequestPathFromUrl(url, serviceName);

        discoveryService(serviceName);

        return HttpUtil.request(restTemplate, getUrl(pollFactory.poller(), requestPath), forwardInfo.getData());
    }

    @Override
    public List<String> discoveryService(String name) {
        try {
            String serviceNode = ZkPathConstant.REGISTRY + "/" + name;

            List<String> childNodeList = getZooKeeper().getChildren().forPath(serviceNode);

            pollFactory.refreshServiceList(childNodeList);

            return childNodeList;
        } catch (Exception e) {
            log.error(e.getMessage());
        }

        return null;
    }

    private String getServiceNameFromUrl(String url) {
        return url.substring(url.indexOf(HttpPathConstant.FORWARD) + HttpPathConstant.FORWARD.length() + 1).split("/")[0];
    }

    private String getRequestPathFromUrl(String url, String serviceName) {
        return url.substring(url.indexOf(serviceName) + serviceName.length());
    }

    private String getUrl(String servicePath, String requestPath) {
        return "http://" + servicePath + requestPath;
    }
}
